unit UltimateSheduler_TaskForm;

interface

uses
  UltimateSheduler_Defines,
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ExtCtrls, XPMan, JvExControls, JvPageList,
  JvSpin, Mask, JvExMask, JvToolEdit, CheckLst;

type
  TUSTaskForm = class(TForm)
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
    LE_Title: TLabeledEdit;
    CB_Enabled: TCheckBox;
    RG_LaunchType: TRadioGroup;
    XPManifest1: TXPManifest;
    GB_LaunchSetup: TGroupBox;
    PL1: TJvPageList;
    LaunchOnTime: TJvStandardPage;
    Label1: TLabel;
    CBX_Launch: TComboBox;
    DtE1: TJvDateEdit;
    TmE1: TJvTimeEdit;
    Label2: TLabel;
    CLB_Days: TCheckListBox;
    SB_Now: TSpeedButton;
    LaunchOnEvent: TJvStandardPage;
    Label3: TLabel;
    SE_Period: TJvSpinEdit;
    CB_Rule: TCheckBox;
    CBX_Rules: TComboBox;
    SB_NewRule: TSpeedButton;
    Label4: TLabel;
    CBX_Actions: TComboBox;
    SB_NewAction: TSpeedButton;
    Label5: TLabel;
    CBX_Events: TComboBox;
    CLB_States: TCheckListBox;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure SB_NowClick(Sender: TObject);
    procedure RG_LaunchTypeClick(Sender: TObject);
    procedure LE_TitleChange(Sender: TObject);
    procedure CB_EnabledClick(Sender: TObject);
    procedure CBX_LaunchChange(Sender: TObject);
    procedure CB_RuleClick(Sender: TObject);
    procedure SB_NewRuleClick(Sender: TObject);
    procedure SB_NewActionClick(Sender: TObject);
    procedure CBX_RulesChange(Sender: TObject);
    procedure CBX_ActionsChange(Sender: TObject);
    procedure CBX_EventsChange(Sender: TObject);
  private
    { Private declarations }
    FTask: Task;
    FRules: TRules;
    FRulesChanged: Boolean;
    FActionGroups: TActionGroups;
    FActionsChanged: Boolean;
    FTaskTitles, FThisTask: String;
    procedure Translate;
    procedure SetTask(NewTask: Task);
    procedure SetRules(NewRules: TRules);
    procedure SetActions(NewActions: TActionGroups);
    procedure SetLaunchType;
    procedure SetLaunchKind;
    procedure SetDaysOfWeek;
    procedure SetDaysOfMonth;
    procedure CheckRule;
    procedure RefreshRules;
    procedure RefreshActions;
  public
    { Public declarations }
    property aTask: Task read FTask write SetTask;
    property Rules: TRules read FRules write SetRules;
    property RulesChanged: Boolean read FRulesChanged;
    property ActionGroups: TActionGroups read FActionGroups write SetActions;
    property ActionsChanged: Boolean read FActionsChanged;
    property TaskTitles: String write FTaskTitles;
    property ThisTask: String write FThisTask;
  end;

implementation

{$R *.dfm}

uses
 gnugettext,
 Tokens,
 StringUtils,
 UltimateSheduler_RuleForm,
 UltimateSheduler_ActionGroupForm,
 DMDownloads;

const
 msgUnknown = 'Unknown %s "%s"!';

procedure TUSTaskForm.FormCreate(Sender: TObject);
begin
 TranslateComponent(self);
 Translate; //some items are not translated automatically
 //
 FTask:=Task.Create(nil);
 FRules:=TRules.Create(Rule);
 FRulesChanged:=false;
 FActionGroups:=TActionGroups.Create(ActionGroup);
 FActionsChanged:=false;
 FTaskTitles:='';
 FThisTask:='';
end;

procedure TUSTaskForm.FormDestroy(Sender: TObject);
begin
 FreeAndNil(FActionGroups);
 FreeAndNil(FRules);
 FreeAndNil(FTask);
end;

procedure TUSTaskForm.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
 var
  i: Integer;
  DT: TDateTime;
begin
 if ModalResult=mrOK then
  begin
   CanClose:=CheckTitle(Self, LE_Title, FTaskTitles, FThisTask);
   if not CanClose then
     Exit;
   //
   case FTask.LaunchType of
    ultTime:
     begin
      case FTask.LaunchKind of
       ultt_Once:
        begin
         DT:=0;
         if TryStrToDate(DtE1.Text, DT) then
          begin
           if TryStrToTime(TmE1.Text, DT) then
             FTask.LaunchData:=DateTimeToStr(DtE1.Date+TmE1.Time)
           else
            begin
             ActiveControl:=TmE1;
             MessageDlg(_('Incorrect time!'), mtError, [mbOK], 0);
            end;
          end
         else
          begin
           ActiveControl:=DtE1;
           MessageDlg(_('Incorrect date!'), mtError, [mbOK], 0);
          end;
         if DT<1 then
          begin
           CanClose:=false;
           Exit;
          end;
        end;
       ultt_Everyday:
        begin
         if TryStrToTime(TmE1.Text, DT) then
           FTask.LaunchData:=TimeToStr(TmE1.Time)
         else
          begin
           ActiveControl:=TmE1;
           MessageDlg(_('Incorrect time!'), mtError, [mbOK], 0);
           CanClose:=false;
           Exit;
          end;
        end;
       ultt_DaysOfWeek, ultt_DaysOfMonth:
        begin
         if TryStrToTime(TmE1.Text, DT) then
          begin
           FTask.LaunchData:=TimeToStr(TmE1.Time);
           for i:=0 to CLB_Days.Count-1 do
            begin
             if CLB_Days.Checked[i] then
               FTask.LaunchData:=FTask.LaunchData+' '+IntToStr(i+1);
            end;
          end
         else
          begin
           ActiveControl:=TmE1;
           MessageDlg(_('Incorrect time!'), mtError, [mbOK], 0);
           CanClose:=false;
           Exit;
          end;
        end;
       ultt_ByPeriod:
        begin
         FTask.LaunchData:=IntToStr(SE_Period.AsInteger);
        end;
       end;
     end;
    ultEvent:
     begin
      FTask.LaunchData:='';
      case FTask.LaunchKind of
       ulte_DownloadState:
        begin
         for i:=0 to CLB_States.Items.Count-1 do
          begin
           if CLB_States.Checked[i] then
            begin
             case i of
              0: FTask.LaunchData:=FTask.LaunchData+' '+IntToStr(dsPause);
              1: FTask.LaunchData:=FTask.LaunchData+' '+IntToStr(dsDownloaded);
              2: FTask.LaunchData:=FTask.LaunchData+' '+IntToStr(dsDownloading);
              3: FTask.LaunchData:=FTask.LaunchData+' '+IntToStr(dsError);
              4: FTask.LaunchData:=FTask.LaunchData+' '+IntToStr(dsQueue);
              end;
            end;
          end;
         if FTask.LaunchData='' then
          begin
           ActiveControl:=CLB_States;
           MessageDlg(_('No states was defined!'), mtError, [mbOK], 0);
           CanClose:=false;
           Exit;
          end;
        end;
       end;
     end;
    end;
   //
   if FTask.RuleTitle<>'' then
    begin
     if FRules.IndexOfTitle(FTask.RuleTitle)<0 then
      begin
       ActiveControl:=CBX_Rules;
       MessageDlg(Format(_(msgUnknown), [_(sRule), FTask.RuleTitle]), mtError, [mbOK], 0);
       CanClose:=false;
       Exit;
      end;
    end;
   //
   if FActionGroups.IndexOfTitle(FTask.ActionsTitle)<0 then
    begin
     ActiveControl:=CBX_Actions;
     MessageDlg(Format(_(msgUnknown), [_(sAG), FTask.ActionsTitle]), mtError, [mbOK], 0);
     CanClose:=false;
     Exit;
    end;
  end;
end;

procedure TUSTaskForm.Translate;
begin
 //
end;

procedure TUSTaskForm.SetTask(NewTask: Task);
begin
 FTask.Assign(NewTask);
 //
 LE_Title.Text:=FTask.Title;
 CB_Enabled.Checked:=FTask.Enabled;
 FTask.LaunchType:=FTask.LaunchType mod 3;
 SetLaunchType;
 //
 RefreshRules;
 RefreshActions;
end;

procedure TUSTaskForm.SetLaunchType;
begin
 RG_LaunchType.ItemIndex:=FTask.LaunchType;
 PL1.Visible:=FTask.LaunchType>0;
 case FTask.LaunchType of
  ultDemand:
   begin
    PL1.Visible:=false;
   end;
  ultTime:
   begin
    PL1.ActivePage:=LaunchOnTime;
    PL1.Visible:=true;
    FTask.LaunchKind:=FTask.LaunchKind mod 5;
    SetLaunchKind;
   end;
  ultEvent:
   begin
    PL1.ActivePage:=LaunchOnEvent;
    PL1.Visible:=true;
    FTask.LaunchKind:=FTask.LaunchKind mod 9;
    SetLaunchKind;
   end;
  end;
end;

procedure TUSTaskForm.SetLaunchKind;
 var
  i, t, k: Integer;
  s: String;
  DT: TDateTime;
begin
 i:=FTask.LaunchKind;
 case FTask.LaunchType of
  ultTime:
   begin
    CBX_Launch.ItemIndex:=i;
    case i of
     ultt_Once:
      begin
       Label2.Visible:=true;
       Label3.Visible:=false;
       DtE1.Visible:=true;
       TmE1.Visible:=true;
       SB_Now.Visible:=true;
       CLB_Days.Visible:=false;
       SE_Period.Visible:=false;
       if TryStrToDateTime(FTask.LaunchData, DT) then
        begin
         DtE1.Date:=DT;
         TmE1.Time:=DT;
        end
       else
        begin
         DtE1.Text:='';
         TmE1.Text:='';
        end;
      end;
     ultt_Everyday:
      begin
       Label2.Visible:=true;
       Label3.Visible:=false;
       DtE1.Visible:=false;
       TmE1.Visible:=true;
       SB_Now.Visible:=true;
       CLB_Days.Visible:=false;
       SE_Period.Visible:=false;
       if TryStrToTime(FTask.LaunchData, DT) then
         TmE1.Time:=DT
       else
         TmE1.Text:='';
      end;
     ultt_DaysOfWeek:
      begin
       Label2.Visible:=true;
       Label3.Visible:=false;
       DtE1.Visible:=false;
       TmE1.Visible:=true;
       SB_Now.Visible:=true;
       SetDaysOfWeek;
       CLB_Days.Visible:=true;
       SE_Period.Visible:=false;
       for t:=1 to WordCount(FTask.LaunchData, [' ']) do
        begin
         s:=ExtractWord(t, FTask.LaunchData, [' ']);
         if t=1 then
          begin
           //time of launch
           if TryStrToTime(s, DT) then
             TmE1.Time:=DT
           else
             TmE1.Text:='';
          end
         else
          begin
           //days of week
           k:=StrToIntDef(s, 0);
           if k>0 then
            begin
             k:=(k-1) mod 7;
             CLB_Days.Checked[k]:=true;
            end;
          end;
        end;
      end;
     ultt_DaysOfMonth:
      begin
       Label2.Visible:=true;
       Label3.Visible:=false;
       DtE1.Visible:=false;
       TmE1.Visible:=true;
       SB_Now.Visible:=true;
       SetDaysOfMonth;
       CLB_Days.Visible:=true;
       SE_Period.Visible:=false;
       for t:=1 to WordCount(FTask.LaunchData, [' ']) do
        begin
         s:=ExtractWord(t, FTask.LaunchData, [' ']);
         if t=1 then
          begin
           //time of launch
           if TryStrToTime(s, DT) then
             TmE1.Time:=DT
           else
             TmE1.Text:='';
          end
         else
          begin
           //days of month
           k:=StrToIntDef(s, 0);
           if k>0 then
            begin
             k:=(k-1) mod 31;
             CLB_Days.Checked[k]:=true;
            end;
          end;
        end;
      end;
     ultt_ByPeriod:
      begin
       Label2.Visible:=true;
       Label3.Visible:=true;
       DtE1.Visible:=true;
       TmE1.Visible:=true;
       SB_Now.Visible:=true;
       CLB_Days.Visible:=false;
       SE_Period.Visible:=true;
       t:=StrToIntDef(FTask.LaunchData, -1);
       if t<0 then
         SE_Period.Value:=SE_Period.MinValue
       else
         SE_Period.Value:=t;
      end;
     end;
   end;
  ultEvent:
   begin
    PL1.ActivePage:=LaunchOnEvent;
    CBX_Events.ItemIndex:=i;
    case i of
     ulte_DownloadState:
      begin
       CLB_States.Visible:=true;
       for t:=0 to CLB_States.Items.Count-1 do
         CLB_States.Checked[t]:=false;
       for t:=1 to WordCount(FTask.LaunchData, [' ']) do
        begin
         s:=ExtractWord(t, FTask.LaunchData, [' ']);
         k:=StrToIntDef(s, -1);
         case k of
          dsPause: CLB_States.Checked[0]:=true;
          dsDownloaded: CLB_States.Checked[1]:=true;
          dsDownloading: CLB_States.Checked[2]:=true;
          dsError: CLB_States.Checked[3]:=true;
          dsQueue: CLB_States.Checked[4]:=true;
          end;
        end;
      end;
     else
       CLB_States.Visible:=false;
     end;
   end;
  end;
end;

procedure TUSTaskForm.SetRules(NewRules: TRules);
begin
 FRules.Assign(NewRules);
 RefreshRules;
end;

procedure TUSTaskForm.SetActions(NewActions: TActionGroups);
begin
 FActionGroups.Assign(NewActions);
 //ShowMessage('Actions in TF: '+IntToStr(FActionGroups.Count)); //debug
 RefreshActions;
end;

procedure TUSTaskForm.SB_NowClick(Sender: TObject);
begin
 DtE1.Date:=Date;
 TmE1.Time:=Time;
end;

procedure TUSTaskForm.SetDaysOfWeek;
 var
  i: Integer;
begin
 CLB_Days.Items.Clear;
 for i:=0 to 6 do
   CLB_Days.Items.Add(_(DaysOfWeek[i]));
end;

procedure TUSTaskForm.SetDaysOfMonth;
 var
  i: Integer;
begin
 CLB_Days.Items.Clear;
 for i:=1 to 31 do
   CLB_Days.Items.Add(IntToStr(i));
end;

procedure TUSTaskForm.RG_LaunchTypeClick(Sender: TObject);
begin
 FTask.LaunchType:=RG_LaunchType.ItemIndex;
 SetLaunchType;
end;

procedure TUSTaskForm.LE_TitleChange(Sender: TObject);
begin
 FTask.Title:=LE_Title.Text;
end;

procedure TUSTaskForm.CB_EnabledClick(Sender: TObject);
begin
 FTask.Enabled:=CB_Enabled.Checked;
end;

procedure TUSTaskForm.CBX_LaunchChange(Sender: TObject);
begin
 FTask.LaunchKind:=CBX_Launch.ItemIndex;
 SetLaunchKind;
end;

procedure TUSTaskForm.CheckRule;
begin
 if CB_Rule.Checked then
   FTask.RuleTitle:=CBX_Rules.Text
 else
   FTask.RuleTitle:='';
 CBX_Rules.Enabled:=CB_Rule.Checked;
 SB_NewRule.Enabled:=CB_Rule.Checked;
end;

procedure TUSTaskForm.CB_RuleClick(Sender: TObject);
begin
 CheckRule;
end;

procedure TUSTaskForm.RefreshRules;
 var
  i: Integer;
begin
 CBX_Rules.Items.Text:=FRules.ListOfTitles;
 if FTask.RuleTitle='' then
   CB_Rule.Checked:=false
 else
  begin
   i:=FRules.IndexOfTitle(FTask.RuleTitle);
   CB_Rule.Checked:=i>=0;
   if i<0 then
     CBX_Rules.ItemIndex:=0
   else
     CBX_Rules.ItemIndex:=i;
  end;
 CheckRule;
end;

procedure TUSTaskForm.RefreshActions;
 var
  i: Integer;
begin
 CBX_Actions.Items.Text:=FActionGroups.ListOfTitles;
 i:=FActionGroups.IndexOfTitle(FTask.ActionsTitle);
 if i<0 then
   CBX_Actions.ItemIndex:=0
 else
   CBX_Actions.ItemIndex:=i;
end;

procedure TUSTaskForm.SB_NewRuleClick(Sender: TObject);
 var
  RF: TUSRuleForm;
begin
 RF:=TUSRuleForm.Create(Self);
 RF.RuleTitles:=FRules.ListOfTitles;
 if RF.ShowModal=mrOK then
  begin
   FRules.Add(myFunction).Assign(RF.myRule);
   RefreshRules;
   FRulesChanged:=true;
  end;
 FreeAndNil(RF);
end;

procedure TUSTaskForm.SB_NewActionClick(Sender: TObject);
 var
  AGF: TUSActionGroupForm;
begin
 AGF:=TUSActionGroupForm.Create(Self);
 AGF.ActionTitles:=FActionGroups.ListOfTitles;
 if AGF.ShowModal=mrOK then
  begin
   FActionGroups.Add.Assign(AGF.myActionGroup);
   RefreshActions;
   FActionsChanged:=true;
  end;
 FreeAndNil(AGF);
end;

procedure TUSTaskForm.CBX_RulesChange(Sender: TObject);
begin
 FTask.RuleTitle:=CBX_Rules.Text; 
end;

procedure TUSTaskForm.CBX_ActionsChange(Sender: TObject);
begin
 FTask.ActionsTitle:=CBX_Actions.Text;
end;

procedure TUSTaskForm.CBX_EventsChange(Sender: TObject);
begin
 FTask.LaunchKind:=CBX_Events.ItemIndex;
 SetLaunchKind;
end;

end.
